﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using BGA;
using BGA.Properties;
using RIO.Enum;
using RIO.Utilits;
using System.Collections.ObjectModel;
using SpeechLib;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;

namespace RIO.Rooms
{
    internal  class BaseRoom
    {
        private struct Chip
        {
            public PlayerColor Color;
            public int Count;
        }

        private Point _boardOffset = new Point(3, 26);
        private Bitmap _boardBitmap;
        private Bitmap _emptyBoardBitmap;

        private ChipDescriptor[] _chipDescriptors =
        {
            #region chip descriptors
		    new ChipDescriptor {Position = 1, Place = ChipPlace.Board, Coord = new Point(665, 445)},
            new ChipDescriptor {Position = 1, Place = ChipPlace.Board, Coord = new Point(658, 412)},
            new ChipDescriptor {Position = 1, Place = ChipPlace.Board, Coord = new Point(651, 379)},
            new ChipDescriptor {Position = 1, Place = ChipPlace.Board, Coord = new Point(646, 346)},
            new ChipDescriptor {Position = 1, Place = ChipPlace.Board, Coord = new Point(639, 313)},
            new ChipDescriptor {Position = 1, Place = ChipPlace.Board, Coord = new Point(632, 290)},
            new ChipDescriptor {Position = 2, Place = ChipPlace.Board, Coord = new Point(618, 445)},
            new ChipDescriptor {Position = 2, Place = ChipPlace.Board, Coord = new Point(612, 412)},
            new ChipDescriptor {Position = 2, Place = ChipPlace.Board, Coord = new Point(606, 379)},
            new ChipDescriptor {Position = 2, Place = ChipPlace.Board, Coord = new Point(600, 346)},
            new ChipDescriptor {Position = 2, Place = ChipPlace.Board, Coord = new Point(595, 313)},
            new ChipDescriptor {Position = 2, Place = ChipPlace.Board, Coord = new Point(590, 290)},
            new ChipDescriptor {Position = 3, Place = ChipPlace.Board, Coord = new Point(577, 445)},
            new ChipDescriptor {Position = 3, Place = ChipPlace.Board, Coord = new Point(572, 412)},
            new ChipDescriptor {Position = 3, Place = ChipPlace.Board, Coord = new Point(566, 379)},
            new ChipDescriptor {Position = 3, Place = ChipPlace.Board, Coord = new Point(560, 346)},
            new ChipDescriptor {Position = 3, Place = ChipPlace.Board, Coord = new Point(554, 313)},
            new ChipDescriptor {Position = 3, Place = ChipPlace.Board, Coord = new Point(548, 290)},
            new ChipDescriptor {Position = 4, Place = ChipPlace.Board, Coord = new Point(530, 445)},
            new ChipDescriptor {Position = 4, Place = ChipPlace.Board, Coord = new Point(527, 412)},
            new ChipDescriptor {Position = 4, Place = ChipPlace.Board, Coord = new Point(524, 379)},
            new ChipDescriptor {Position = 4, Place = ChipPlace.Board, Coord = new Point(521, 346)},
            new ChipDescriptor {Position = 4, Place = ChipPlace.Board, Coord = new Point(518, 313)},
            new ChipDescriptor {Position = 4, Place = ChipPlace.Board, Coord = new Point(515, 290)},
            new ChipDescriptor {Position = 5, Place = ChipPlace.Board, Coord = new Point(485, 445)},
            new ChipDescriptor {Position = 5, Place = ChipPlace.Board, Coord = new Point(483, 412)},
            new ChipDescriptor {Position = 5, Place = ChipPlace.Board, Coord = new Point(481, 379)},
            new ChipDescriptor {Position = 5, Place = ChipPlace.Board, Coord = new Point(479, 346)},
            new ChipDescriptor {Position = 5, Place = ChipPlace.Board, Coord = new Point(477, 313)},
            new ChipDescriptor {Position = 5, Place = ChipPlace.Board, Coord = new Point(475, 290)},
            new ChipDescriptor {Position = 6, Place = ChipPlace.Board, Coord = new Point(442, 445)},
            new ChipDescriptor {Position = 6, Place = ChipPlace.Board, Coord = new Point(441, 412)},
            new ChipDescriptor {Position = 6, Place = ChipPlace.Board, Coord = new Point(440, 379)},
            new ChipDescriptor {Position = 6, Place = ChipPlace.Board, Coord = new Point(439, 346)},
            new ChipDescriptor {Position = 6, Place = ChipPlace.Board, Coord = new Point(438, 313)},
            new ChipDescriptor {Position = 6, Place = ChipPlace.Board, Coord = new Point(437, 290)},
            new ChipDescriptor {Position = 7, Place = ChipPlace.Board, Coord = new Point(356, 445)},
            new ChipDescriptor {Position = 7, Place = ChipPlace.Board, Coord = new Point(357, 412)},
            new ChipDescriptor {Position = 7, Place = ChipPlace.Board, Coord = new Point(358, 379)},
            new ChipDescriptor {Position = 7, Place = ChipPlace.Board, Coord = new Point(359, 346)},
            new ChipDescriptor {Position = 7, Place = ChipPlace.Board, Coord = new Point(360, 313)},
            new ChipDescriptor {Position = 7, Place = ChipPlace.Board, Coord = new Point(361, 290)},
            new ChipDescriptor {Position = 8, Place = ChipPlace.Board, Coord = new Point(312, 445)},
            new ChipDescriptor {Position = 8, Place = ChipPlace.Board, Coord = new Point(314, 412)},
            new ChipDescriptor {Position = 8, Place = ChipPlace.Board, Coord = new Point(316, 379)},
            new ChipDescriptor {Position = 8, Place = ChipPlace.Board, Coord = new Point(318, 346)},
            new ChipDescriptor {Position = 8, Place = ChipPlace.Board, Coord = new Point(320, 313)},
            new ChipDescriptor {Position = 8, Place = ChipPlace.Board, Coord = new Point(322, 290)},
            new ChipDescriptor {Position = 9, Place = ChipPlace.Board, Coord = new Point(267, 445)},
            new ChipDescriptor {Position = 9, Place = ChipPlace.Board, Coord = new Point(269, 412)},
            new ChipDescriptor {Position = 9, Place = ChipPlace.Board, Coord = new Point(271, 379)},
            new ChipDescriptor {Position = 9, Place = ChipPlace.Board, Coord = new Point(273, 346)},
            new ChipDescriptor {Position = 9, Place = ChipPlace.Board, Coord = new Point(275, 313)},
            new ChipDescriptor {Position = 9, Place = ChipPlace.Board, Coord = new Point(277, 290)},
            new ChipDescriptor {Position = 10, Place = ChipPlace.Board, Coord = new Point(224, 445)},
            new ChipDescriptor {Position = 10, Place = ChipPlace.Board, Coord = new Point(227, 412)},
            new ChipDescriptor {Position = 10, Place = ChipPlace.Board, Coord = new Point(230, 379)},
            new ChipDescriptor {Position = 10, Place = ChipPlace.Board, Coord = new Point(233, 346)},
            new ChipDescriptor {Position = 10, Place = ChipPlace.Board, Coord = new Point(236, 313)},
            new ChipDescriptor {Position = 10, Place = ChipPlace.Board, Coord = new Point(239, 290)},
            new ChipDescriptor {Position = 11, Place = ChipPlace.Board, Coord = new Point(182, 445)},
            new ChipDescriptor {Position = 11, Place = ChipPlace.Board, Coord = new Point(184, 412)},
            new ChipDescriptor {Position = 11, Place = ChipPlace.Board, Coord = new Point(188, 379)},
            new ChipDescriptor {Position = 11, Place = ChipPlace.Board, Coord = new Point(192, 346)},
            new ChipDescriptor {Position = 11, Place = ChipPlace.Board, Coord = new Point(196, 313)},
            new ChipDescriptor {Position = 11, Place = ChipPlace.Board, Coord = new Point(202, 290)},
            new ChipDescriptor {Position = 12, Place = ChipPlace.Board, Coord = new Point(134, 445)},
            new ChipDescriptor {Position = 12, Place = ChipPlace.Board, Coord = new Point(139, 412)},
            new ChipDescriptor {Position = 12, Place = ChipPlace.Board, Coord = new Point(144, 379)},
            new ChipDescriptor {Position = 12, Place = ChipPlace.Board, Coord = new Point(149, 346)},
            new ChipDescriptor {Position = 12, Place = ChipPlace.Board, Coord = new Point(154, 313)},
            new ChipDescriptor {Position = 12, Place = ChipPlace.Board, Coord = new Point(159, 290)},
            new ChipDescriptor {Position = 13, Place = ChipPlace.Board, Coord = new Point(198, 81)},
            new ChipDescriptor {Position = 13, Place = ChipPlace.Board, Coord = new Point(193, 103)},
            new ChipDescriptor {Position = 13, Place = ChipPlace.Board, Coord = new Point(188, 126)},
            new ChipDescriptor {Position = 13, Place = ChipPlace.Board, Coord = new Point(184, 150)},
            new ChipDescriptor {Position = 13, Place = ChipPlace.Board, Coord = new Point(181, 175)},
            new ChipDescriptor {Position = 13, Place = ChipPlace.Board, Coord = new Point(179, 200)},
            new ChipDescriptor {Position = 14, Place = ChipPlace.Board, Coord = new Point(230, 81)},
            new ChipDescriptor {Position = 14, Place = ChipPlace.Board, Coord = new Point(227, 103)},
            new ChipDescriptor {Position = 14, Place = ChipPlace.Board, Coord = new Point(224, 126)},
            new ChipDescriptor {Position = 14, Place = ChipPlace.Board, Coord = new Point(221, 150)},
            new ChipDescriptor {Position = 14, Place = ChipPlace.Board, Coord = new Point(218, 175)},
            new ChipDescriptor {Position = 14, Place = ChipPlace.Board, Coord = new Point(215, 200)},
            new ChipDescriptor {Position = 15, Place = ChipPlace.Board, Coord = new Point(262, 81)},
            new ChipDescriptor {Position = 15, Place = ChipPlace.Board, Coord = new Point(260, 103)},
            new ChipDescriptor {Position = 15, Place = ChipPlace.Board, Coord = new Point(258, 126)},
            new ChipDescriptor {Position = 15, Place = ChipPlace.Board, Coord = new Point(256, 150)},
            new ChipDescriptor {Position = 15, Place = ChipPlace.Board, Coord = new Point(254, 175)},
            new ChipDescriptor {Position = 15, Place = ChipPlace.Board, Coord = new Point(252, 200)},
            new ChipDescriptor {Position = 16, Place = ChipPlace.Board, Coord = new Point(300, 81)},
            new ChipDescriptor {Position = 16, Place = ChipPlace.Board, Coord = new Point(298, 103)},
            new ChipDescriptor {Position = 16, Place = ChipPlace.Board, Coord = new Point(296, 126)},
            new ChipDescriptor {Position = 16, Place = ChipPlace.Board, Coord = new Point(294, 150)},
            new ChipDescriptor {Position = 16, Place = ChipPlace.Board, Coord = new Point(292, 175)},
            new ChipDescriptor {Position = 16, Place = ChipPlace.Board, Coord = new Point(290, 200)},
            new ChipDescriptor {Position = 17, Place = ChipPlace.Board, Coord = new Point(334, 81)},
            new ChipDescriptor {Position = 17, Place = ChipPlace.Board, Coord = new Point(332, 103)},
            new ChipDescriptor {Position = 17, Place = ChipPlace.Board, Coord = new Point(330, 126)},
            new ChipDescriptor {Position = 17, Place = ChipPlace.Board, Coord = new Point(328, 150)},
            new ChipDescriptor {Position = 17, Place = ChipPlace.Board, Coord = new Point(327, 175)},
            new ChipDescriptor {Position = 17, Place = ChipPlace.Board, Coord = new Point(326, 200)},
            new ChipDescriptor {Position = 18, Place = ChipPlace.Board, Coord = new Point(368, 81)},
            new ChipDescriptor {Position = 18, Place = ChipPlace.Board, Coord = new Point(367, 103)},
            new ChipDescriptor {Position = 18, Place = ChipPlace.Board, Coord = new Point(366, 126)},
            new ChipDescriptor {Position = 18, Place = ChipPlace.Board, Coord = new Point(365, 150)},
            new ChipDescriptor {Position = 18, Place = ChipPlace.Board, Coord = new Point(364, 175)},
            new ChipDescriptor {Position = 18, Place = ChipPlace.Board, Coord = new Point(363, 200)},
            new ChipDescriptor {Position = 19, Place = ChipPlace.Board, Coord = new Point(430, 81)},
            new ChipDescriptor {Position = 19, Place = ChipPlace.Board, Coord = new Point(430, 103)},
            new ChipDescriptor {Position = 19, Place = ChipPlace.Board, Coord = new Point(430, 126)},
            new ChipDescriptor {Position = 19, Place = ChipPlace.Board, Coord = new Point(431, 150)},
            new ChipDescriptor {Position = 19, Place = ChipPlace.Board, Coord = new Point(432, 175)},
            new ChipDescriptor {Position = 19, Place = ChipPlace.Board, Coord = new Point(433, 200)},
            new ChipDescriptor {Position = 20, Place = ChipPlace.Board, Coord = new Point(463, 81)},
            new ChipDescriptor {Position = 20, Place = ChipPlace.Board, Coord = new Point(464, 103)},
            new ChipDescriptor {Position = 20, Place = ChipPlace.Board, Coord = new Point(465, 126)},
            new ChipDescriptor {Position = 20, Place = ChipPlace.Board, Coord = new Point(468, 150)},
            new ChipDescriptor {Position = 20, Place = ChipPlace.Board, Coord = new Point(469, 175)},
            new ChipDescriptor {Position = 20, Place = ChipPlace.Board, Coord = new Point(470, 200)},
            new ChipDescriptor {Position = 21, Place = ChipPlace.Board, Coord = new Point(496, 81)},
            new ChipDescriptor {Position = 21, Place = ChipPlace.Board, Coord = new Point(498, 103)},
            new ChipDescriptor {Position = 21, Place = ChipPlace.Board, Coord = new Point(500, 126)},
            new ChipDescriptor {Position = 21, Place = ChipPlace.Board, Coord = new Point(503, 150)},
            new ChipDescriptor {Position = 21, Place = ChipPlace.Board, Coord = new Point(506, 175)},
            new ChipDescriptor {Position = 21, Place = ChipPlace.Board, Coord = new Point(510, 200)},
            new ChipDescriptor {Position = 22, Place = ChipPlace.Board, Coord = new Point(529, 81)},
            new ChipDescriptor {Position = 22, Place = ChipPlace.Board, Coord = new Point(531, 103)},
            new ChipDescriptor {Position = 22, Place = ChipPlace.Board, Coord = new Point(534, 126)},
            new ChipDescriptor {Position = 22, Place = ChipPlace.Board, Coord = new Point(538, 150)},
            new ChipDescriptor {Position = 22, Place = ChipPlace.Board, Coord = new Point(541, 175)},
            new ChipDescriptor {Position = 22, Place = ChipPlace.Board, Coord = new Point(545, 200)},
            new ChipDescriptor {Position = 23, Place = ChipPlace.Board, Coord = new Point(566, 81)},
            new ChipDescriptor {Position = 23, Place = ChipPlace.Board, Coord = new Point(568, 103)},
            new ChipDescriptor {Position = 23, Place = ChipPlace.Board, Coord = new Point(571, 126)},
            new ChipDescriptor {Position = 23, Place = ChipPlace.Board, Coord = new Point(575, 150)},
            new ChipDescriptor {Position = 23, Place = ChipPlace.Board, Coord = new Point(578, 175)},
            new ChipDescriptor {Position = 23, Place = ChipPlace.Board, Coord = new Point(582, 200)},
            new ChipDescriptor {Position = 24, Place = ChipPlace.Board, Coord = new Point(600, 81)},
            new ChipDescriptor {Position = 24, Place = ChipPlace.Board, Coord = new Point(603, 103)},
            new ChipDescriptor {Position = 24, Place = ChipPlace.Board, Coord = new Point(606, 126)},
            new ChipDescriptor {Position = 24, Place = ChipPlace.Board, Coord = new Point(610, 150)},
            new ChipDescriptor {Position = 24, Place = ChipPlace.Board, Coord = new Point(614, 175)},
            new ChipDescriptor {Position = 24, Place = ChipPlace.Board, Coord = new Point(618, 200)},

            new ChipDescriptor {Position = 6, Place = ChipPlace.Board, Coord = new Point(425, 434), Size = new Size(1, 1)},
            new ChipDescriptor {Position = 8, Place = ChipPlace.Board, Coord = new Point(293, 439), Size = new Size(1, 1)},
            new ChipDescriptor {Position = 12, Place = ChipPlace.Board, Coord = new Point(122, 428), Size = new Size(1, 1)},
            new ChipDescriptor {Position = 13, Place = ChipPlace.Board, Coord = new Point(180, 80), Size = new Size(1, 1)},
            new ChipDescriptor {Position = 19, Place = ChipPlace.Board, Coord = new Point(443, 74), Size = new Size(1, 1)},


            new ChipDescriptor {Position = 0, Place = ChipPlace.Bar, Coord = new Point(400, 290)},
            new ChipDescriptor {Position = 0, Place = ChipPlace.Bar, Coord = new Point(398, 220)},
            new ChipDescriptor {Position = 0, Place = ChipPlace.Bar, Coord = new Point(398, 182)},
	#endregion
        };

        private DiceDescriptor[] _dices =
        {
            new DiceDescriptor
            {
                Position = new Point(488, 219),
                Size = new Size(28, 24),
                Features = new Dictionary<PlayerColor, int[]>
                {
                    {PlayerColor.White, new int[] { 6, 14, 23, 27, 34, 43 }},
                    {PlayerColor.Black, new int[] { 6, 16, 23, 30, 37, 45 }},
                }
            },
            new DiceDescriptor
            {
                Position = new Point(546, 219),
                Size = new Size(28, 24),
                Features = new Dictionary<PlayerColor, int[]>
                {
                    {PlayerColor.White, new int[] { 6, 14, 23, 27, 34, 43 }},
                    {PlayerColor.Black, new int[] { 6, 16, 23, 30, 37, 45 }},
                }
            },
        };
        
        private PlayerColor _playerColor { get; set; }

        private string _snowieText;

        private Collection<String> _hintInformation = new Collection<string>();
        private int _hintCurrentNumber = 0;
        SpVoice _speaker = new SpVoice();

        private bool IsDebugMode { get; set; }


        public BaseRoom()
        {
            IsDebugMode = false;
            IsDebugMode = true;

            _chipDescriptors.Where(x => x.Size.IsEmpty).ForEach(x => x.Size = new Size(16, 16));

            //InitializeCoords();
            InitializeBitmaps();
            InitializeComponents();
        }

        //protected abstract string GetWindow


        private void InitializeBitmaps()
        {
            _emptyBoardBitmap = BGA.Resources.Resource.PartyBoard;
        }

       

        private void InitializeComponents()
        {
            ISpeechObjectTokens voices = _speaker.GetVoices("Name=Alyona22k", "");
            if (voices.Count == 0)
            {
                MessageBox.Show("Голосовой движок Алена22к не установлен. Чтение будет на EN и не точным.");
                return;
            }

            _speaker.Voice = voices.Item(0);
        }

        private bool UpdateBoardBitmap()
        {
            //_boardBitmap = new Bitmap(@"Screen\15.01.2012 20_28_29.bmp");
            _boardBitmap = Utilits.WindowCapture.GetWindowBitmap("User = ");
            if (_boardBitmap == null)
                return false;

            //ImageHelper.ShowImage(_boardBitmap);
            return true;
        }
     

        private bool UpdateDices()
        {
            Bitmap debugBmp = new Bitmap(_boardBitmap);
            Graphics debugGrp = Graphics.FromImage(debugBmp);

            _playerColor = PlayerColor.None;

            int diceFound = 0;
            using (var fastBoardBitmap = new FastBitmap(_boardBitmap))
            {
                //for (int i = 0; i < _dices.Length; i++)
                foreach (var dice in _dices)
                {
                    int whiteCount = 0;
                    int blackCount = 0;
                    for (int x = dice.Position.X; x < dice.Position.X + dice.Size.Width; x++)
                    {
                        for (int y = dice.Position.Y; y < dice.Position.Y + dice.Size.Height; y++)
                        {
                            if (ImageHelper.CompareColor(fastBoardBitmap.GetColor(x, y), Color.Black, 50))
                                whiteCount++;
                            if (ImageHelper.CompareColor(fastBoardBitmap.GetColor(x, y), Color.White, 50))
                                blackCount++;
                        }
                    }

                    //debugGrp.DrawString(whiteCount.ToString() + ", " + blackCount.ToString(), new Font("Arial", 10), Brushes.Black, _diceCoords[i].X, _diceCoords[i].Y + 40);
                    //ImageHelper.ShowImage(debugBmp);

                    if (_playerColor == PlayerColor.None)
                    {
                        if (whiteCount > 0 && whiteCount < 50)
                            _playerColor = PlayerColor.White;
                        else if (blackCount > 0 && blackCount < 50)
                            _playerColor = PlayerColor.Black;
                        else
                            return false;
                    }

                    dice.TrySetValue(_playerColor, _playerColor == PlayerColor.White ? whiteCount : blackCount);
                }
            }

            if (_dices.Any(x => x.Value == 0))
                return false;

            return true;
        }

        private bool UpdateChips()
        {
            Bitmap debugBmp = new Bitmap(_boardBitmap);
            Graphics debugGrp = Graphics.FromImage(debugBmp);

            using (var boardFastBitmap = new FastBitmap(_boardBitmap))
            using (var emptyBoardFastBitmap = new FastBitmap(_emptyBoardBitmap))
            {
                // Закрашиваем доску
                Point boardPoint = new Point();
                Color color1;
                Color color2;
                for (int i = 0; i < _emptyBoardBitmap.Width; i++)
                {
                    for (int j = 0; j < _emptyBoardBitmap.Height - _boardOffset.Y; j++)
                    {
                        boardPoint.X = _boardOffset.X + i;
                        boardPoint.Y = _boardOffset.Y + j;
                        color1 = boardFastBitmap.GetColor(boardPoint.X, boardPoint.Y);
                        color2 = emptyBoardFastBitmap.GetColor(i, j);
                        if (color1.ToArgb() == color2.ToArgb())
                        {
                            boardFastBitmap.SetColor(boardPoint.X, boardPoint.Y, Color.Aqua);
                        }
                    }
                }
                
                //обнуляем прошлые цвета чипов
                _chipDescriptors.ForEach(x => x.PlayerColor = PlayerColor.None);

                // находим фишки
                //for (int i = 0; i < 24; i++)
                foreach (var chipDescriptor in _chipDescriptors)
                {
                    //// 6 в столбик не было, пропускаем
                    //if (chipDescriptor.Position == 6)
                    //    continue;

                    int colorFeature = 0;
                    for (int w = 0; w < chipDescriptor.Size.Width; w++)
                        for (int h = 0; h < chipDescriptor.Size.Height; h++)
                        {
                            colorFeature += boardFastBitmap
                                .GetColor(chipDescriptor.Coord.X - chipDescriptor.Size.Width / 2 + w, chipDescriptor.Coord.Y - chipDescriptor.Size.Height / 2 + h)
                                .AvgColor();
                        }
                    colorFeature = colorFeature / (chipDescriptor.Size.Width * chipDescriptor.Size.Height);

                    if (IsDebugMode)
                    {
                        debugGrp.FillRectangle(new SolidBrush(Color.White), new Rectangle(chipDescriptor.LeftTopCorner.X, chipDescriptor.LeftTopCorner.Y, chipDescriptor.Size.Width, chipDescriptor.Size.Height));
                        debugGrp.DrawRectangle(new Pen(Color.Green), new Rectangle(chipDescriptor.LeftTopCorner.X, chipDescriptor.LeftTopCorner.Y, chipDescriptor.Size.Width, chipDescriptor.Size.Height));
                        debugGrp.DrawString(colorFeature.ToString(), new Font("Arial", 8), Brushes.Black, chipDescriptor.LeftTopCorner.X, chipDescriptor.LeftTopCorner.Y);
                    }

                    if (colorFeature > 200)
                    {
                        if (chipDescriptor.PlayerColor == PlayerColor.Black)
                        {
                            MessageBox.Show("В одном пунтке обнаружены и черные и белые фишки!");
                            return false;
                        }
                        chipDescriptor.PlayerColor = PlayerColor.White;
                        if (IsDebugMode)
                        {
                            debugGrp.DrawRectangle(new Pen(Color.Red), new Rectangle(chipDescriptor.LeftTopCorner.X, chipDescriptor.LeftTopCorner.Y, chipDescriptor.Size.Width, chipDescriptor.Size.Height));
                        }
                    }
                    else if (colorFeature < 100)
                    {
                        if (chipDescriptor.PlayerColor == PlayerColor.White)
                        {
                            MessageBox.Show("В одном пунтке обнаружены и черные и белые фишки!");
                            return false;
                        }
                        chipDescriptor.PlayerColor = PlayerColor.Black;
                        if (IsDebugMode)
                        {
                            debugGrp.DrawRectangle(new Pen(Color.Blue), new Rectangle(chipDescriptor.LeftTopCorner.X, chipDescriptor.LeftTopCorner.Y, chipDescriptor.Size.Width, chipDescriptor.Size.Height));
                        }
                    }
                }

                if (IsDebugMode)
                {
                    DebugImageForm.ShowForm(null, debugBmp);
                    //ImageHelper.ShowImage(debugBmp);
                }

                int count = _chipDescriptors.Count(x => x.PlayerColor != PlayerColor.None);

                if (count != 30)
                {
                    _speaker.Speak("Не все фишки найдены");
                    SaveScreenshot();
                    return false;
                }

                // 12
                Point point6 = new Point(127, 428);
                Color color6 = boardFastBitmap.GetColor(point6.X, point6.Y);
                
                if (color6.R == 1)
                {

                }

            } // FastBitmap

            //ImageHelper.ShowImage(debugBmp);

            return true;
        }

        private bool UpdateSnowieText()
        {
            //  Field 
            //1 Match length, 0 means unlimited (money game)
            //2 1 means Jacoby rule applies, 0 otherwise.
            //3 Could not figure out this one!
            //4 0 = money game, 1 = match game. / ?
            //5 Player on roll 0 = first player, 1 = second player.
            //6 First Player name.
            //7 Second Player name.
            //8 1 = Crawford game, 0 otherwise.
            //9 Score for first player.
            //10 Score for second player.
            //11 Cube value
            //12 Cube ownership: 1 = player-on-roll, 0 = centred, -1 = player-not-on-roll.
            //13 Player-on-roll?s number of chequers on the bar. 
            //14..37 Points 1 to 24. Values: 0 = empty, otherwise, absolute value number of checkers
            //38 Player-not-on-roll?s number of chequers on the bar.
            //39,40 Current dice values: (0,0) = not rolled.
            StringBuilder sb = new StringBuilder();
            // описание игры
            sb.Append("0;0;0;1;1;First;Second;0;0;0;");
            // куб
            sb.Append("1;0;");
            // фишки на баре 13 player NOT on roll
            sb.AppendFormat("{0};", _chipDescriptors.Count(x => x.PlayerColor != _playerColor && x.PlayerColor != PlayerColor.None && x.Place == ChipPlace.Bar));
            // фишки 14..37
            for (int i = 1; i <= 24; i++)
            {
                int count = _chipDescriptors.Count(x => x.Place == ChipPlace.Board && x.Position == i && x.PlayerColor != PlayerColor.None);
                var playerColor = _chipDescriptors.First(x => x.Place == ChipPlace.Board && x.Position == i).PlayerColor;
                sb.AppendFormat("{0};", playerColor == _playerColor ? count : -count);
            }
            // фишки на баре 38 player on roll
            sb.AppendFormat("{0};", _chipDescriptors.Count(x => x.PlayerColor == _playerColor && x.Place == ChipPlace.Bar));
            // зары
            sb.AppendFormat("{0};{1};", _dices[0].Value, _dices[1].Value);

            _snowieText = sb.ToString();
            return true;
        }

        private bool UpdateHintInformation()
        {
            using (StreamWriter file = new StreamWriter(@"cli\samples\position.txt"))
            {
                file.Write(_snowieText);
            }

            using (var process = new Process())
            {
                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                process.StartInfo.FileName = @"cli\rio-cli.exe";
                process.StartInfo.Arguments = @"--commands=samples\commands.txt --quiet";
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.Start();
                
                var result = new StringBuilder();
                // хз зачем это нужно, но без этого иногда зависает
                while(!process.HasExited)
                    result.Append(process.StandardOutput.ReadToEnd()); 
                
                //var outputLine = process.StandardOutput.ReadLine();
                //while (!string.IsNullOrEmpty(outputLine))
                //{
                //    result.AppendLine(outputLine);
                //    outputLine = process.StandardOutput.ReadLine();
                //    ////process.BeginOutputReadLine();
                //    //if (!process.HasExited)
                //    //    result.AppendLine(process.StandardOutput.ReadToEnd());
                //}
                process.Close();

                //1. Cubeful 0-ply    15/11(2)                     Eq.:  +0,313
                //   0,609 0,034 0,001 - 0,391 0,038 0,000
                //    0-ply cubeful [expert]
                //2. Cubeful 0-ply    15/13(2) 8/6 3/1             Eq.:  +0,194 ( -0,120)
                //   0,572 0,035 0,000 - 0,428 0,049 0,000
                //    0-ply cubeful [expert]
                Regex r = new Regex(@"\d\. .*ply( *.* {5})");
                MatchCollection match = r.Matches(result.ToString());

                _hintInformation.Clear();
                for (int i = 0; i < match.Count; i++)
                {
                    _hintInformation.Add(match[i].Groups[1].Value.Trim().Replace("/", "в").Replace("*", "Шот;").Replace(" ", ";"));
                }
            }

            if (_hintInformation.Count == 0)
            {
                MessageBox.Show("Решений не найдено");
                return false;
            }

            return true;
        }

        private void SayHint()
        {
            if (_hintCurrentNumber < _hintInformation.Count)
            {
                _speaker.Speak(_hintInformation[_hintCurrentNumber]);
            }

            _hintCurrentNumber++;
            if (_hintCurrentNumber > _hintInformation.Count - 1)
            {
                _speaker.Speak("Вариантов больше нет.");
                _hintCurrentNumber = 0;
            }
        }


        public void GetHint()
        {
            if (!UpdateBoardBitmap())
            {
                _speaker.Speak("Окно не найдено!");
                return;
            }

            //if (!UpdatePlayerChipColor())
            //{
            //    _speaker.Speak("Цвет фишек игрока не определен");
            //    return;
            //}

            if (!UpdateDices())
            {
                _speaker.Speak("Кубики не найдены");
                return;
            }

            if (!UpdateChips())
                return;

            if (!UpdateSnowieText())
                return;

            if (!UpdateHintInformation())
                return;

            _hintCurrentNumber = 0;
            SayHint();
        }

        public void GetNextHint()
        {
            _hintCurrentNumber++;
            SayHint();
        }

        public void SaveScreenshot()
        {
            Bitmap _boardBitmap = Utilits.WindowCapture.GetWindowBitmap("User = ");
            if (_boardBitmap != null)
            {
                //_boardBitmap.Save(string.Format("Screen\\{0}.bmp", DateTime.Now.ToString().Replace(":", "_")));
            }
        }

        public void ShowDebugScreen()
        {
            throw new NotImplementedException();
        }
    }
}
